package com.zzyq.pc.common.plugin.shiro;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;

import com.zzyq.pc.utils.INI4J;
import com.zzyq.pc.utils.LoggerUtils;

/**
 * 
 * <p>
 * 
 * @Title: ShiroManager.java
 * @Description: 用于加载并重构ShiroFilter配置
 * @author: Sywd丶吴迪
 * @date: 2017年8月30日 下午1:30:32
 * @version V1.0
 *          <p>
 */
public class ShiroManager {
    private static final String CRLF = System.getProperty("line.separator");
    @Resource
    @Autowired
    private ShiroFilterFactoryBean shiroFilterFactoryBean;

    /**
     * 加载过滤配置信息
     */
    public String loadFilterChainDefinitions() {
        StringBuffer sb = new StringBuffer();
        sb.append(getFixedAuthRule());// 固定权限，采用读取配置文件
        return sb.toString();
    }

    /**
     * 从配额文件获取固定权限验证规则串
     */
    private String getFixedAuthRule() {
        String fileName = "properties/shiro_filter.properties";
        ClassPathResource cp = new ClassPathResource(fileName);
        INI4J ini = null;
        try {
            ini = new INI4J(cp.getFile());
        } catch (IOException e) {
            LoggerUtils.fmtError(getClass(), e, "加载文件出错。file:[%s]", fileName);
        }
        String section = "base_auth";
        Set<String> keys = ini.get(section).keySet();
        StringBuffer sb = new StringBuffer();
        for (String key : keys) {
            String value = ini.get(section, key);
            sb.append(key).append(" = ").append(value).append(CRLF);
        }

        return sb.toString();

    }

    /**
     * 此方法加同步锁
     * <p>
     * 重新构建权限过滤器
     * <p>
     * 一般在修改了用户角色、用户等信息时，需要再次调用该方法
     */
    public synchronized void reCreateFilterChains() {
        AbstractShiroFilter shiroFilter = null;
        try {
            shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
        } catch (Exception e) {
            LoggerUtils.error(getClass(), "获取shiroFilter出错!", e);
            throw new RuntimeException("获取shiroFilter出错!");
        }

        PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
                .getFilterChainResolver();
        DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();

        // 清空老的权限控制
        manager.getFilterChains().clear();

        shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
        shiroFilterFactoryBean.setFilterChainDefinitions(loadFilterChainDefinitions());
        // 重新构建生成
        Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
        for (Map.Entry<String, String> entry : chains.entrySet()) {
            String url = entry.getKey();
            String chainDefinition = entry.getValue().trim().replace(" ", "");
            manager.createChain(url, chainDefinition);
        }

    }

    public void setShiroFilterFactoryBean(ShiroFilterFactoryBean shiroFilterFactoryBean) {
        this.shiroFilterFactoryBean = shiroFilterFactoryBean;
    }
}
